package org.hiucung.hlsdownloader.utils

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okio.buffer
import okio.sink
import okio.source
import java.io.File

/**
 * @Classname TsMerger
 * @Description TS文件合成
 * @Date 2025/8/21 14:01
 * @Created by Kicc
 */
class TsMerger {

    /**
     * 使用Okio高效合并TS文件（推荐）
     */
    suspend fun mergeTsFilesWithOkio(
        tsFilePaths: List<String>,
        outputPath: String,
        onProgress: suspend (Int, Int) -> Unit = { _, _ -> }
    ): Result<File> = withContext(Dispatchers.IO) {
        return@withContext try {
            val outputFile = File(outputPath)

            if (outputFile.exists()) {
                outputFile.delete()
            }
            outputFile.sink().buffer().use { sink ->
                tsFilePaths.forEachIndexed { index, tsPath ->

                    val tsFile = File(tsPath)
                    if (tsFile.exists()) {
                        tsFile.source().buffer().use { source ->
                            sink.writeAll(source)
                        }
                        // 更新进度
                        onProgress(index + 1, tsFilePaths.size)
                    }
                }
            }

            Result.success(outputFile)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    /**
     * 使用标准Java IO合并TS文件
     */
    suspend fun mergeTsFiles(
        tsFilePaths: List<String>,
        outputPath: String,
        onProgress: suspend (Int, Int) -> Unit = { _, _ -> }
    ): Result<File> = withContext(Dispatchers.IO) {
        return@withContext try {
            val outputFile = File(outputPath)
            if (outputFile.exists()) {
                outputFile.delete()
            }

            File(outputPath).outputStream().use { outputStream ->
                val buffer = ByteArray(8192)

                tsFilePaths.forEachIndexed { index, tsPath ->
                    val tsFile = File(tsPath)
                    if (tsFile.exists()) {
                        tsFile.inputStream().use { inputStream ->
                            var bytesRead: Int
                            while (inputStream.read(buffer).also { bytesRead = it } != -1) {
                                outputStream.write(buffer, 0, bytesRead)
                            }
                        }
                        // 更新进度
                        onProgress(index + 1, tsFilePaths.size)
                    }
                }

                outputStream.flush()
            }

            Result.success(File(outputPath))
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
}